package rs.dalao.syc.passport.config;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import rs.dalao.syc.common.response.JsonResult;
import rs.dalao.syc.common.response.ServiceCode;
import rs.dalao.syc.passport.filter.JwtAuthorizationFilter;
import rs.dalao.syc.passport.security.UserDetailsServiceImpl;
import springfox.documentation.spring.web.json.Json;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private JwtAuthorizationFilter jwtAuthorizationFilter;
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    //密码编码器
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    //登录认证器
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // 允许跨域访问
        http.cors();

        // 配置Spring Security不再使用Session
        // 注意：不要使用NEVER，它表示的是“不主动创建Session”，但是，当Session已存在时，仍会使用
        // 推荐使用STATELESS，它表示的是“无状态”，无论是否存在Session都不会使用
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        //将解析JWT的过滤器添加到Spring Security框架的过滤器链中
        http.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);

        //处理无认证信息却尝试访问需要通过登录认证后进行访问的资源的异常
        http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
            public void commence(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                String message = "当前未登录，或登录信息已过期，请登录";
                JsonResult jsonResult = JsonResult.fail(ServiceCode.ERROR_UNAUTHORIZED, message);
                String jsonResultString = JSON.toJSONString(jsonResult);
                response.setContentType("application/json;charset=utf-8");
                PrintWriter printWriter = response.getWriter();
                printWriter.println(jsonResultString);
                printWriter.close();
            }
        });



        String [] urls={
                "/doc.html",
                "/**/*.js",
                "/**/*.css",
                "/swagger-resources",
                "/v2/api-docs",
                "/favicon.ico",
                "/test/simple-get",
                "/test/simple-post",
                "/passport/users/login",
                "/passport/users/reg",
                "/passport/users/logout",
                "/passport/doctors/reg",
                "/passport/doctors/login",
                "/passport/doctors/logout",
                "/vaccine/vaccineList/*",
                "/aid/category/*",
                "/aid/**",
                "/passport/users/getCode",
                "/passport/users/getCode/*",
                "/passport/users/getCode/**",


        };
        //配置请求授权
        http.authorizeRequests()
                .mvcMatchers(urls).permitAll()
                .anyRequest().authenticated();
        //配置自己的登录界面
        //http.formLogin();
        //关闭“”防御伪造跨域攻击的防御机制
        http.csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //指定用于加载普通用户的认证信息
        auth.userDetailsService(userDetailsService);
    }
}
